/**
 * 
 */
package baduga.client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;


import javax.net.ssl.SSLSocket;

import baduga.core.Core_Exception;
import baduga.core.Core_JsonDataSchema;
import baduga.core.Core_Messages;


public final class Network_API__ClientThread extends Thread {
	
	/** Socket SSL dla klienta */
	private SSLSocket clientSocketSSL;
	
	/** Bufory */
	private BufferedReader 	inboundData;
	private BufferedWriter 	outboundData;
	
	/** Informacja czy klient jest połączony */
	public static boolean conected = false;
	
	/** informacja czy klient nadał */
	public static boolean replystatus = true;
	
	/** Kontroler Sieciowy*/
	private Network_Call__Controler nContr = new Network_Call__Controler();
	
	
	
	
	public Network_API__ClientThread(SSLSocket socket, boolean nConected)
	{
		clientSocketSSL = socket;
		conected = nConected;
		
		
		makeConnect();
	}
	
	
	private void makeConnect()
	{
		if(conected)
		{

			try {
				inboundData = new BufferedReader(new InputStreamReader(clientSocketSSL.getInputStream()));
				outboundData = new BufferedWriter(new OutputStreamWriter(clientSocketSSL.getOutputStream()));
			} catch (IOException e1) {
				//TODO: DBG_IMPROVE_FUTURE
				Core_Exception.showOwnMessage(Core_Messages.getMessage(0x02FA), Core_Messages.getMessage(0x0100));
				conected = false;
			}
		}
	}
	
	
	/**
	 * Funkcja rozłączająca klienta zwraca status operacji
	 * 
	 * Powodzenie: true
	 * Wpadka: False
	 * 
	 * @return
	 */
	public boolean disConnect()
	{
		boolean opStatus = false;
		
		if(conected)
		{

			//Przerwanie
			conected = false;
			
			try {
				//Zamkniecie socketa
				if(clientSocketSSL != null)
					clientSocketSSL.close();
				
				
				//Zamknięcie strumienii
				if(inboundData != null)
					inboundData.close();
				
				if(outboundData != null)
					outboundData.close();


				
				opStatus = true;
			} catch (IOException e) {
				//TODO: DBG_IMPROVE_FUTURE
				Core_Exception.showOwnMessage(Core_Messages.getMessage(0x02F9), Core_Messages.getMessage(0x0100));
			}

		}
		return opStatus;

	}
	
	
	/**
	 * Funkcja pobierane dane od serwera
	 */
	public void readData()
	{
		if(conected)
		{
			String input = "";
			
			
			Network_Api netwAPI = Controler.getNetwAPI();
			
			/** Struktura danych */
			Core_JsonDataSchema inStructure = null;
			

			try {
				
				while(!this.isInterrupted()  &&  (input = inboundData.readLine()) != null && conected)
				{
					
					System.out.println("INPUT: \n " + input + " \n");
					
					inStructure = netwAPI.decodeJson(input);
					
					
					if(inStructure != null)
					{
						/*
						System.out.println("KOD: " + inStructure.getKod()  + "| ARGS : " + inStructure.getArgs()[0]  + "|\n"
								+ " Dane: \n"
								+ "[0]" +  inStructure.getDataD1()[0] 
								+ "[1]" +  inStructure.getDataD1()[1]);
						*/
						
						nContr.globalSwitch(inStructure);
						
						
					
						//Informacja, że doszło
						if(replystatus == false)
						{
							replystatus = true;
							
							
							
						}
						
						
						
					}
					
				}
				
			} catch (IOException e) {
				//TODO: DBG_IMPROVE_FUTURE
				Core_Exception.showOwnMessage(Core_Messages.getMessage(0x02F8), Core_Messages.getMessage(0x0100));
				
				conected = false;
			}
			
		}
	}
	
	/**
	 * Wysyłane ciąg danych do serwera
	 * 
	 * @param data
	 */
	public boolean sendData(Core_JsonDataSchema data)
	{
		boolean opStatus = true;
		
		if(conected)
		{
			Network_Api netwAPI = Controler.getNetwAPI();
			
			String tmp = "";
			
			
			
			try {
				tmp = netwAPI.encodeJson(data);
				
				
			} catch (IOException e) {
				//TODO: DBG_IMPROVE_FUTURE
				Core_Exception.showOwnMessage(Core_Messages.getMessage(0x02F7), Core_Messages.getMessage(0x0100));
				
				opStatus = false;
			}

			//Dodanie znaku końca lini
			tmp += '\n';
			
			if(opStatus == true)
			{
				try {
					outboundData.write( tmp );
					
					outboundData.flush();
					
					System.out.println("OUPUT: \n " + tmp + " \n");
					
					replystatus = false;
				} catch (IOException e) {
					//TODO: DBG_IMPROVE_FUTURE
					Core_Exception.showOwnMessage(Core_Messages.getMessage(0x02F5), Core_Messages.getMessage(0x0100));	
				}
			}
		}
		else
		{
			opStatus = false;
		}
		
		return opStatus;
	}
	
	
	
	/**
	 * 
	 * Odpalacz wątku
	 * 
	 */
	
	@Override
	public void run()
	{
		
		/**  Kiedy niespodziewanie serwer chce iśc spać */
		Runtime.getRuntime().addShutdownHook(new Thread("Gracefull Shutodwn") {
			
			@Override
			public void run() {
				//Uśpienie wątku
				disConnect();
			}
			
		});
		

		readData();

		
	}
	

	


}
